﻿using System;
using System.Security.Cryptography;

namespace Org.Mentalis.Security.Cryptography
{
	// Token: 0x0200001F RID: 31
	public sealed class HMAC : KeyedHashAlgorithm
	{
		// Token: 0x060000FE RID: 254 RVA: 0x00006A0C File Offset: 0x00005A0C
		public HMAC(HashAlgorithm hash) : this(hash, null)
		{
		}

		// Token: 0x060000FF RID: 255 RVA: 0x00006A24 File Offset: 0x00005A24
		public HMAC(HashAlgorithm hash, byte[] rgbKey)
		{
			if (hash == null)
			{
				throw new ArgumentNullException();
			}
			if (rgbKey == null)
			{
				rgbKey = new byte[hash.HashSize / 8];
				new RNGCryptoServiceProvider().GetBytes(rgbKey);
			}
			this.m_HashAlgorithm = hash;
			this.Key = (byte[])rgbKey.Clone();
			this.m_IsDisposed = false;
			this.m_KeyBuffer = new byte[64];
			this.m_Padded = new byte[64];
			this.Initialize();
		}

		// Token: 0x06000100 RID: 256 RVA: 0x00006A9C File Offset: 0x00005A9C
		public override void Initialize()
		{
			if (this.m_IsDisposed)
			{
				throw new ObjectDisposedException(base.GetType().FullName);
			}
			this.m_HashAlgorithm.Initialize();
			this.m_IsHashing = false;
			this.State = 0;
			Array.Clear(this.m_KeyBuffer, 0, this.m_KeyBuffer.Length);
		}

		// Token: 0x06000101 RID: 257 RVA: 0x00006AF0 File Offset: 0x00005AF0
		protected override void HashCore(byte[] rgb, int ib, int cb)
		{
			if (this.m_IsDisposed)
			{
				throw new ObjectDisposedException(base.GetType().FullName);
			}
			if (!this.m_IsHashing)
			{
				byte[] array;
				if (this.Key.Length > 64)
				{
					array = this.m_HashAlgorithm.ComputeHash(this.Key);
				}
				else
				{
					array = this.Key;
				}
				Array.Copy(array, 0, this.m_KeyBuffer, 0, array.Length);
				for (int i = 0; i < 64; i++)
				{
					this.m_Padded[i] = (byte)(m_KeyBuffer[i] ^ 54);
				}
				this.m_HashAlgorithm.TransformBlock(this.m_Padded, 0, this.m_Padded.Length, this.m_Padded, 0);
				this.m_IsHashing = true;
			}
			this.m_HashAlgorithm.TransformBlock(rgb, ib, cb, rgb, ib);
		}

		// Token: 0x06000102 RID: 258 RVA: 0x00006BB4 File Offset: 0x00005BB4
		protected override byte[] HashFinal()
		{
			if (this.m_IsDisposed)
			{
				throw new ObjectDisposedException(base.GetType().FullName);
			}
			this.m_HashAlgorithm.TransformFinalBlock(new byte[0], 0, 0);
			byte[] hash = this.m_HashAlgorithm.Hash;
			for (int i = 0; i < 64; i++)
			{
				this.m_Padded[i] = (byte)(this.m_KeyBuffer[i] ^ 92);
			}
			this.m_HashAlgorithm.Initialize();
			this.m_HashAlgorithm.TransformBlock(this.m_Padded, 0, this.m_Padded.Length, this.m_Padded, 0);
			this.m_HashAlgorithm.TransformFinalBlock(hash, 0, hash.Length);
			hash = this.m_HashAlgorithm.Hash;
			Array.Clear(this.m_KeyBuffer, 0, this.m_KeyBuffer.Length);
			this.m_IsHashing = false;
			return hash;
		}

		// Token: 0x1700002C RID: 44
		// (get) Token: 0x06000103 RID: 259 RVA: 0x00006C84 File Offset: 0x00005C84
		public override int HashSize
		{
			get
			{
				return this.m_HashAlgorithm.HashSize;
			}
		}

		// Token: 0x06000104 RID: 260 RVA: 0x00006C9C File Offset: 0x00005C9C
		protected override void Dispose(bool disposing)
		{
			this.m_IsDisposed = true;
			base.Dispose(true);
			this.m_HashAlgorithm.Clear();
			try
			{
				GC.SuppressFinalize(this);
			}
			catch
			{
			}
		}

		// Token: 0x06000105 RID: 261 RVA: 0x00006CEC File Offset: 0x00005CEC
		~HMAC()
		{
			this.m_HashAlgorithm.Clear();
		}

		// Token: 0x04000094 RID: 148
		private HashAlgorithm m_HashAlgorithm;

		// Token: 0x04000095 RID: 149
		private byte[] m_KeyBuffer;

		// Token: 0x04000096 RID: 150
		private bool m_IsHashing;

		// Token: 0x04000097 RID: 151
		private bool m_IsDisposed;

		// Token: 0x04000098 RID: 152
		private byte[] m_Padded;
	}
}
